#!/usr/bin/python -u

#DEBUG
import cgitb
cgitb.enable(display=1, logdir="/tmp/cgitb")

import libxml2
import libxslt
import os
import sys
import StringIO
import cgi
import re

sys.path.append('./lib')
import renyare
import renyare.config as config

def main():
	form = cgi.FieldStorage()
	global conf
	conf = config.config(renyare.paths)
	pDoc = libxml2.parseFile("/var/www/renyare/htdocs/modules/pic_dirs.xml")
	outDoc = libxml2.newDoc('1.0')
	pi = outDoc.newDocPI('xml-stylesheet', 'type="text/xsl" href="/pics_edit.xsl"')
	outDoc.addChild(pi)
	out = outDoc.newDocNode(None, 'pics', None)
	outDoc.setRootElement(out)
	global message
	message = out.newChild(None,'message',None)
	# Make the list of directories inside /pics
	pics = renyare.paths['local']+conf['local']['images']
	osDirs = os.listdir(pics)
	# Make the list of directories in xml-file
	ctxt = pDoc.xpathNewContext()
	xDirs = ctxt.xpathEval('/dirs/*')
	dRoot = pDoc.getRootElement()
	found = [];
	# Remove non-existent directories from the list
	for dir in xDirs:
		if(dir.name == 'dir' and dir.hasProp('name')):
			if(dir.prop('name') in osDirs):
				found.append(dir.prop('name'))
			else:
				dir.unlinkNode()
				dir.freeNode()
	# Add the directories, that are not in the list
	for dir in osDirs:
		if((not dir in found) and os.path.isdir(pics+dir)):
			d = dRoot.newChild(None, 'dir', None)
			d.setProp('name', dir)
			d.newChild(None, 'descr', None)
	# If "Delete" button pressed, delete the contents of the directory if there is access to them
	if(form.getfirst("del")):
		for dir in osDirs:
			if(form.getfirst("dir") == dir):
				xDirs = ctxt.xpathEval("/dirs/dir[@name='"+dir+"']")
				if(xDirs):
					xDirs[0].unlinkNode()
					xDirs[0].freeNode()
					ok = True
					for root, dirs, files in os.walk(pics+dir, topdown=False):
						for name in files:
							if(os.access(os.path.join(root,name), os.W_OK)):
								os.remove(os.path.join(root,name))
							else:
								message.addContent("Can't delete "+name+". No access")
								ok=False	
						for name in dirs:
							if(os.access(os.path.join(root,name), os.W_OK)):
								os.rmdir(os.path.join(root,name))
							else:
								message.addContent("Can't delete "+name+". No access")
								ok=False
					if(ok): os.rmdir(pics+dir)
	out.addChild(pDoc.getRootElement().copyNode(1))
	# If "Show" button pressed
	if(form.getfirst("curdir")):
		dir = form.getfirst("curdir")
		message.addContent("CURDIR"+dir)
		if dir in osDirs:
			out.newChild(None, 'curdir', dir)
		else:
			out.newChild(None, 'curdir', None)
	if(form.getfirst("picsOk") and form.getfirst("curdir")):
		curdir = form.getfirst("curdir").lstrip('/')
		global id
		id = 0
		indexDir(os.path.join(pics,curdir), message, addPic, addDir, ['thumbs'], 'image')
	#########################
	# Final output
	#########################
	#res = StringIO.StringIO()
	#outDoc.dump(res)
	#print res.getvalue()
	print "Content-type: application/xml\n"
	print str(outDoc)
	outDoc.freeDoc()
	pDoc.freeDoc()
	ctxt.xpathFreeContext()

def indexDir(path, node, fileFunc, dirFunc, exclude=[], fileNode='file', dirNode='dir'):
	a = os.listdir(path)
	for obj in a:
		ok = True
		for ex in exclude:
			if re.search(ex, obj):
				ok = False
		if(ok):
			full = os.path.join(path,obj)
			if(os.path.isdir(full)):
				newNode = dirFunc(path, obj, node, exclude, dirNode)
				indexDir(full, newNode, fileFunc, dirFunc, exclude, fileNode, dirNode)
			if(os.path.isfile(full)):
				fileFunc(path, obj, node, exclude, fileNode)

def addDir(path, obj, node, exclude, dirNode):
	b = node.newChild(None, dirNode, None)
	newPath = re.sub(conf.htdocs, '/', os.path.join(path,obj))
	b.setProp('path', newPath)
	return b
	
def addPic(path, obj, node, exclude, fileNode):
	if(re.search('\.jpg$', obj)):
		b = node.newChild(None, 'image', None)
		file = b.newChild(None, 'file', None)
		thumb = b.newChild(None, 'thumb', None)
		newPath = re.sub(conf.htdocs, '/', os.path.join(path,obj))
		thumbPath = re.sub(conf.htdocs, '/', os.path.join(path,os.path.join('thumbs', obj)))
		global id
		id += 1
		b.setProp('id', str(id))
		file.setProp('path', newPath)
		thumb.setProp('path', thumbPath)

main()

#~ use strict;
#~ no strict 'refs';
#~ use lib 'lib';
#~ use lib './include';
#~ use Image::Magick;
#~ use XML::LibXML;
#~ use SiteConf;
#~ my $cf = SiteConf::new();
#~ my $thumbsDir='thumbs';
#~ my $picsDir = 'pics';
#~ my $picsConfig = $cf->{'staticDir'}.'pics.xml';
#~ my $noDescr = 'No Description';
#~ our $output = "";
#~ my $doc = "";
#~ if(not -e $picsConfig){
#~ $doc = XML::LibXML::Document->createDocument( "1.0", "UTF-8" );
#~ $doc->setDocumentElement($doc->createElement('dirs'));
#~ }
#~ else {
#~ my $parser = XML::LibXML->new();
#~ $doc = $parser->parse_file($picsConfig);
#~ }
#~ # Check if all directories listed in xml exist
#~ my @dirNodes = $doc->findnodes('/dirs/dir');
#~ my $found = "";
#~ foreach my $dir (@dirNodes){
	#~ map { $found=1 if($_ eq $cf->{'htdocs'}.$dir->getAttribute('name')); } keys(%$dirlist);
	#~ if(not $found) { $dir->parentNode->removeChild($dir); }
#~ }

#~ foreach my $dir (keys(%$dirlist)){
	#~ my @nodes = $doc->findnodes('/dirs/dir[@name=\''.stripPath($dir).'\']');
	#~ if (not @nodes){	# If the directory is not in the list - i.e. when a new dir has been created
		#~ my $dirnode = $doc->documentElement->addNewChild(undef, 'dir');
		#~ $dirnode->setAttribute('name', '/'.stripPath($dir));
		#~ foreach my $file(@{$dirlist->{$dir}}){
			#~ addImage($dirnode, @$file);
		#~ }
	#~ }
	#~ else {
		#~ my $files = $nodes[0]->find('image/file');
		#~ my $found = 0;
		#~ my @toadd = ();
		#~ my @toremove = ();
		#~ # First, we clean non-existent files
		#~ foreach my $fileInXml (@$files) { # for every found file...
			#~ $found = 0;
			#~ foreach my $fileInHash (@{$dirlist->{$dir}}){ # ...and for every file listed in XML
				#~ if($fileInXml->getAttribute('path') eq $fileInHash->[0]) { 
					#~ $found = 1; 
				#~ }
			#~ }
			#~ if(not $found) {
				#~ push (@toremove, $fileInXml->parentNode);
			#~ }
		#~ }
		#~ foreach my $remnode (@toremove){ # Remove the entries recorded and the thumbnails
			
			#~ my $thumb = $remnode->getChildrenByTagName('thumb')->[0]->getAttribute('path');
			#~ if(-e $thumb) { unlink $thumb; }
			#~ $remnode->parentNode->removeChild($remnode);
		#~ }
		#~ foreach my $fileInHash (@{$dirlist->{$dir}}){
			#~ $found = 0;
			#~ foreach my $fileInXml (@$files) {	
				#~ if($fileInXml->getAttribute('path') eq $fileInHash->[0]){
					#~ my $thumb = $fileInXml->parentNode->getChildrenByTagName('thumb');
					#~ if($thumb) { $thumb->[0]->setAttribute('path', $fileInHash->[1]); }
					#~ else { $nodes[0]->addNewChild(undef, 'thumb')->setAttribute('path', $fileInHash->[1]); }
					#~ $found = 1;
				#~ }
			#~ }
			#~ if(not $found){
				#~ push (@toadd, $fileInHash);
			#~ }
		#~ }
		#~ foreach my $addnode (@toadd){
			#~ addImage($nodes[0], @$addnode);
		#~ }
	#~ }
#~ }
#~ #print "Content-type: text/xml\n\n";
#~ print "Content-type: text/html\n\n";
#~ $doc->toFile($picsConfig);
#~ #print $doc->toString($picsConfig);
#~ my $xml = "";

#~ # Check if the thumbnail for the filename supplied exists in the $thumbsDir and create it if it's not. 
#~ sub makeThumb {
#~ my ($filename) = @_;
#~ my $path = $filename;
#~ $path =~ /([^\/]*)$/;
#~ my $file = $1;			# Filename without a path is stored here
#~ $path =~ s/$file$//g; 		# Remove the filename from the path
#~ $path =~ s/\/$//g; 		# Remove the trailing slash from the path
#~ my $newfn = $path."/$thumbsDir/$file";
#~ if(not -e $newfn) { # If the thumbnail does not exist
	#~ my $image = Image::Magick->new;
	#~ my $imgFile = $image->Read($filename);
	#~ my ($w,$h) = $image->Get('base-columns','base-rows');
	#~ my $ratio = 150/(($w>$h)?$w:$h);
	#~ $w = $w*$ratio;
	#~ $h = $h*$ratio; 
	#~ no strict 'subs';
	#~ $image->Resize(geometry=>geometry, width=>$w, height=>$h);
	#~ use strict 'subs';
	#~ $imgFile = $image->Write($newfn);
	#~ }
#~ return $newfn;
#~ }

#~ # Add the image to the provided node
#~ sub addImage {
#~ my ($node, $path, $thumb, $descr) = @_;
	#~ my $imgnode = $node->addNewChild(undef, 'image');
	#~ $imgnode->addNewChild(undef, 'file')->setAttribute('path', '/'.stripPath($path));
	#~ $imgnode->addNewChild(undef, 'thumb')->setAttribute('path', '/'.stripPath($thumb));
	#~ $imgnode->addNewChild(undef, 'descr')->appendText($descr);
#~ }

#~ sub stripPath {
	#~ my $stripped = shift(@_);
	#~ $stripped =~ s/$cf->{'htdocs'}//g;
	#~ $stripped =~ s/^\///;
	#~ return $stripped; 
#~ }
#~ 1;
